package com.tencent.texttoimage.hook;


import android.content.Context;


import com.tencent.texttoimage.BuildConfig;

import org.apache.commons.lang3.StringUtils;

import dalvik.system.PathClassLoader;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

import android.content.Context;


import com.tencent.texttoimage.BuildConfig;

import org.apache.commons.lang3.StringUtils;

import dalvik.system.PathClassLoader;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class Injector implements IXposedHookLoadPackage {
    public static final String TAG = "TextToImage";
    private static final String QQ_PACKAGE_NAME = "com.tencent.mobileqq";
    private static final String WECHAT_PACKAGE_NAME = "com.tencent.mm";

    private static String MODULE_PATH = null;


    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        if (QQ_PACKAGE_NAME.equals(lpparam.packageName)) {

            XposedHelpers.findAndHookMethod("com.tencent.mobileqq.qfix.QFixApplication", lpparam.classLoader, "attachBaseContext", Context.class, new XC_MethodHook() {

                @Override
                protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
                    XposedBridge.log(TAG + ": QFixApplication::attachBaseContext");

                    Context context = (Context) param.args[0];
                    MODULE_PATH = context.getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0).sourceDir;

                    if (StringUtils.isEmpty(MODULE_PATH)) {
                        XposedBridge.log(TAG + ": dynamic load module failed, use default hook instead");
                        QQHook.doHook(context.getClassLoader(), context);
                    } else {
                        XposedBridge.log(TAG + ": dynamic load module: " + MODULE_PATH);
                        PathClassLoader pathClassLoader = new PathClassLoader(MODULE_PATH, Injector.class.getClassLoader().getParent());

                        Class<?> injectorClass = pathClassLoader.loadClass(Injector.class.getName());
                        XposedHelpers.findField(injectorClass, "MODULE_PATH").set(null, MODULE_PATH);

                        Class<?> qQHookClass = pathClassLoader.loadClass(QQHook.class.getName());
                        XposedHelpers.findMethodExact(qQHookClass, "doHook", ClassLoader.class, Context.class)
                                .invoke(null, context.getClassLoader(), context);
                    }

                }
            });
        } else if (WECHAT_PACKAGE_NAME.equals(lpparam.packageName)) {
            XposedHelpers.findAndHookMethod("com.tencent.tinker.loader.app.TinkerApplication", lpparam.classLoader, "attachBaseContext", Context.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    XposedBridge.log(TAG + ": TinkerApplication::attachBaseContext");

                    Context context = (Context) param.args[0];
                    MODULE_PATH = context.getPackageManager().getApplicationInfo(BuildConfig.APPLICATION_ID, 0).sourceDir;

                    if (StringUtils.isEmpty(MODULE_PATH)) {
                        XposedBridge.log(TAG + ": dynamic load module failed, use default hook instead");
                        QQHook.doHook(context.getClassLoader(), context);
                    } else {
                        XposedBridge.log(TAG + ": dynamic load module: " + MODULE_PATH);
                        PathClassLoader pathClassLoader = new PathClassLoader(MODULE_PATH, Injector.class.getClassLoader().getParent());

                        Class<?> injectorClass = pathClassLoader.loadClass(Injector.class.getName());
                        XposedHelpers.findField(injectorClass, "MODULE_PATH").set(null, MODULE_PATH);

                        Class<?> weChatHookClass = pathClassLoader.loadClass(WeChatHook.class.getName());
                        XposedHelpers.findMethodExact(weChatHookClass, "doHook", ClassLoader.class, Context.class)
                                .invoke(null, context.getClassLoader(), context);
                    }

                }
            });

        }

    }

}